package com.itheima.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.bean.*;
import com.itheima.dto.OrdersDto;
import com.itheima.exception.MyException;
import com.itheima.mapper.OrderMapper;
import com.itheima.mapper.UserMapper;
import com.itheima.service.AddressBookService;
import com.itheima.service.OrderDetailService;
import com.itheima.service.OrderService;
import com.itheima.service.ShoppingCartService;
import com.itheima.utils.BaseContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author hebing
 * @version 1.0
 */
@Service
@Transactional
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private AddressBookService addressBookService;

    @Autowired
    private ShoppingCartService shoppingCartService;

    @Autowired
    private OrderDetailService orderDetailService;

    @Autowired
    private UserMapper userMapper;

    /**
     * 分页查询
     *
     * @param params
     * @return
     */
    @Override
    public IPage<Orders> findPage(PageParams params) {
        //设置分页查询条件
        IPage<Orders> ordersIPage = new Page<>(params.getPage(), params.getPageSize());
        LambdaQueryWrapper<Orders> lqw = new LambdaQueryWrapper<>();
        //设置number条件
        lqw.eq(params.getNumber() != null, Orders::getNumber, params.getNumber());
        //设置订单时间的时间区域
        lqw.between(params.getBeginTime() != null, Orders::getOrderTime, params.getBeginTime(), params.getEndTime());
        //查询并返回
        return orderMapper.selectPage(ordersIPage, lqw);
    }

    /**
     * 修改订单状态
     *
     * @param orders
     * @return
     */
    @Override
    public int updateStatus(Orders orders) {
        //根据id查询数据库
        Orders order = orderMapper.selectById(orders.getId());
        //判断状态
        if (order.getStatus() == 4) {
            throw new MyException("该订单已经完成");
        } else {
            //修改状态
            order.setStatus(4);
            //修改数据库
            int rows = orderMapper.updateById(order);
            //返回
            return rows;
        }
    }

    /**
     * 提交订单
     *
     * @param orders
     * @return
     */
    @Override
    public Orders submit(Orders orders, User user) {
        //需要提交两份表 一份是订单表 一份是订单详细表
        //构建订单表数据 雪花算法生成用户编号
        //设置编号和number为同一个数值
        long id = IdWorker.getId();
        //订单id
        orders.setId(id);
        //编号number
        orders.setNumber(String.valueOf(id));
        //订单支付状态
        orders.setStatus(1);
        //下单用户号
        orders.setUserId(BaseContext.getCurrentId());
        //地址id不用填写 前端已经提交
        //下单时间 当前时间
        orders.setOrderTime(LocalDateTime.now());
        //结账时间 当前时间
        orders.setCheckoutTime(LocalDateTime.now());
        //支付方式也有了 不用写
        //实收金额也有了 不用写
        //备注也有了 不用写
        //用户名 由用户表传过来
        orders.setUserName(user.getName());
        //根据用户id查询地址簿
        LambdaQueryWrapper<AddressBook> lqw = new LambdaQueryWrapper<>();
        lqw.eq(AddressBook::getUserId, BaseContext.getCurrentId());
        AddressBook addressBook = addressBookService.getOne(lqw);
        //手机号
        orders.setPhone(addressBook.getPhone());
        //地址 省市区+详细地址
        orders.setAddress(
                (addressBook.getProvinceName() != null ? addressBook.getProvinceName() : "") +
                        (addressBook.getCityName() != null ? addressBook.getCityName() : "") +
                        (addressBook.getDistrictName() != null ? addressBook.getDistrictName() : "") +
                        (addressBook.getDetail() != null ? addressBook.getDetail() : "")
        );
        //收货人
        orders.setConsignee(addressBook.getConsignee());
        //调用dao保存到数据库
        orderMapper.insert(orders);

        //构建订单详情表
        //查询购物车
        List<ShoppingCart> shoppingCartList = shoppingCartService.selectByUserId(BaseContext.getCurrentId());
        //判断
        if (shoppingCartList != null && shoppingCartList.size() > 0) {
            List<OrderDetail> orderDetailList = shoppingCartList.stream().map(shoppingCart -> {
                //创建订单详细对象
                OrderDetail orderDetail = new OrderDetail();
                //拷贝数据
                BeanUtils.copyProperties(shoppingCart, orderDetail);
                //设置订单id
                orderDetail.setOrderId(id);
                //返回 用于封装
                return orderDetail;
            }).collect(Collectors.toList());
            //将数据保存到订单详细表中
            orderDetailService.save(orderDetailList);
        }
        //添加完毕清空购物车
        shoppingCartService.clean();
        //返回订单数据
        return orders;
    }

    /**
     * 根据提供的信息进行分页查询用户表
     *
     * @param params
     * @return
     */
    @Override
    public IPage<OrdersDto> findUserPage(PageParams params) {
        //构建分页查询结果对象
        IPage<Orders> ordersPage = new Page<>(params.getPage(), params.getPageSize());
        //查询条件
        LambdaQueryWrapper<Orders> lqw = new LambdaQueryWrapper<>();
        //设置付款时间降序
        lqw.orderByDesc(Orders::getCheckoutTime);
        //根据用户id来查
        lqw.eq(Orders::getUserId,BaseContext.getCurrentId());
        //分页查询
        orderMapper.selectPage(ordersPage, lqw);
        //创建OrdersDto对象 作为返回结果集
        IPage<OrdersDto> ordersDtoIPage=new Page<>();
        //设置查询总记录数
        ordersDtoIPage.setTotal(ordersPage.getTotal());
        //拷贝数据
        List<Orders> ordersList = ordersPage.getRecords();
        if(ordersList!=null&&ordersList.size()>0){
            List<OrdersDto> ordersDtoList = ordersList.stream().map(orders -> {
                //创建ordersDto对象
                OrdersDto ordersDto = new OrdersDto();
                //拷贝数据
                BeanUtils.copyProperties(orders, ordersDto);
                //根据订单id查询订单详情
                List<OrderDetail> orderDetailList = orderDetailService.seletByOrdersId(orders.getId());
                //赋值
                ordersDto.setOrderDetails(orderDetailList);
                //返回对象用于封装
                return ordersDto;
            }).collect(Collectors.toList());
            //给返回值OrdersDto对象赋值
            ordersDtoIPage.setRecords(ordersDtoList);
            //返回对象
            return ordersDtoIPage;
        }
        //没订单
        return null;
    }

}
